<script setup lang="ts">
import { type PropType, ref, type VNode } from "vue";
import { ExclamationCircleFilled } from "@ant-design/icons-vue";

defineOptions({ name: "confirm-button" });

// 预设内容
const presetContents = {
  delete: "确定要删除吗？",
  confirm: "确定要执行吗？",
  edit: "确定要修改吗？",
  add: "确定要添加吗？",
  cancel: "确定要取消吗？",
  save: "确定要保存吗？",
  reset: "确定要重置吗？",
  restore: "确定要恢复吗？",
};

const props = defineProps({
  type: { type: String as PropType<"default" | "primary" | "text" | "dashed" | "link" | "ghost"> },
  size: { type: String as PropType<"large" | "middle" | "small"> },
  shape: { type: String as PropType<"default" | "circle" | "round"> },
  icon: { type: Object as PropType<VNode> },
  htmlType: { type: String },
  disabled: { type: Boolean, default: () => undefined },
  block: { type: Boolean, default: () => undefined },
  danger: { type: Boolean, default: () => undefined },
  loading: { type: Boolean, default: () => undefined },
  prevent: { type: Boolean, default: false },
  stop: { type: Boolean, default: false },

  title: { type: String, default: "提示" },
  content: { type: String },
  preset: { type: String as PropType<keyof typeof presetContents> },
  beforeConfirm: { type: Function as PropType<(...args: any[]) => boolean | Promise<boolean>> },
  confirmCb: { type: Function as PropType<(...args: any[]) => any> },
  confirmArg: { type: [Number, Boolean, String, BigInt, Object, Array] as PropType<any> },
  cancelCb: { type: Function as PropType<(...args: any[]) => any> },
});

const emits = defineEmits({
  ok: () => true,
  cancel: () => true,
});

const modalOpen = ref(false);

const onClick = async (e: PointerEvent) => {
  if (props.prevent) e.preventDefault();
  if (props.stop) e.stopPropagation();

  if (props.beforeConfirm) {
    const next = await props.beforeConfirm(...(props.confirmArg ? [props.confirmArg, e] : [e]));
    if (!next) return;
  }

  if (modalOpen.value) return;
  modalOpen.value = true;
  // return;
  // Modal.confirm({
  //   centered: true,
  //   title: props.title || "提示",
  //   content: props.content,
  //   onOk: (...args: any[]) => {
  //     emits("ok");
  //     const confirmArgs = [...args];
  //     if (props.confirmArg != null) {
  //       if (Array.isArray(props.confirmArg)) {
  //         confirmArgs.unshift(...props.confirmArg);
  //       } else {
  //         confirmArgs.unshift(props.confirmArg);
  //       }
  //     }
  //     return props.confirmCb?.(...confirmArgs);
  //   },
  //   onCancel: (...args: any[]) => {
  //     emits("cancel");
  //     return props.cancelCb?.(...args);
  //   },
  // });
};

const handleConfirm = (...args: any[]) => {
  try {
    emits("ok");
    const confirmArgs = [...args];
    if (props.confirmArg != null) {
      if (Array.isArray(props.confirmArg)) {
        confirmArgs.unshift(...props.confirmArg);
      } else {
        confirmArgs.unshift(props.confirmArg);
      }
    }
    return props.confirmCb?.(...confirmArgs);
  } finally {
    modalOpen.value = false;
  }
};

const handleCancel = (...args: any[]) => {
  try {
    emits("cancel");
    return props.cancelCb?.(...args);
  } finally {
    modalOpen.value = false;
  }
};
</script>

<template>
  <a-button
    :type="type"
    :size="size"
    :danger="danger"
    :icon="icon"
    :shape="shape"
    :html-type="htmlType"
    :loading="loading"
    :disabled="disabled"
    @click.prevent.stop="onClick"
  >
    <slot />
  </a-button>
  <a-modal
    v-if="modalOpen"
    v-model:open="modalOpen"
    :closable="false"
    :mask-closable="false"
    centered
    width="416px"
    @cancel.stop.prevent="handleCancel"
    @ok.stop.prevent="handleConfirm"
  >
    <template #title>
      <div class="flex aic col-gap-10">
        <ExclamationCircleFilled class="color-warning font-22" />
        <span>{{ title }}</span>
      </div>
    </template>
    <div class="confirm-modal-content">
      <slot name="content">{{ content || (preset && presetContents[preset]) }}</slot>
    </div>
  </a-modal>
</template>

<style lang="less">
.confirm-modal-content {
  text-indent: 32px;
  word-break: break-all;
  user-select: text;
}
</style>
